home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / ABox 1.9.5 / CPlus Files / ABLinkedList.c next >
Encoding:
C/C++ Source or Header  |  1995-10-26  |  9.5 KB  |  428 lines  |  [TEXT/MMCC]

  1. /*    
  2.     Copyright © 1991-1995 by TopSoft Inc.  All rights reserved.
  3.  
  4.     You may distribute this file under the terms of the TopSoft
  5.     Artistic License, accompanying this package.
  6.     
  7.     This file was developed by George (ty) Tempel in connection with TopSoft, Inc..
  8.     See the Modification History for more details.
  9.  
  10. Product
  11.     About Box
  12.  
  13. FILE
  14.     ABLinkedList.c
  15.  
  16. NAME
  17.     ABLinkedList.c, part of the ABox project source code,
  18.     responsible for handling the AboutBox linked list class stuff.
  19.  
  20. DESCRIPTION
  21.     This file contains defines for the about box modules.
  22.     
  23. DEVELOPED BY
  24.     George (ty) Tempel                ttempel@monmouth.com
  25.     All code in this file, and its associated header file was
  26.     Created by George (ty) Tempel in connection with the TopSoft, Inc.
  27.     "FilterTop" application development, except where noted.
  28.  
  29. CARETAKER - George (ty) Tempel <ttempel@monmouth.com>
  30.      Please consult this person for any changes or suggestions to this file.
  31.  
  32. MODIFICATION HISTORY
  33.  
  34.     dd mmm yy    -    xxx    -    patchxx: description of patch
  35.     9 June 94    -    ty    -    Initial Version Created
  36.     20-july-94    -    ty    -    initial version released
  37.     23-may-95    -    ty    -    changes for compatibility with the CodeWarrior CW6
  38.                             release and the associated Universal Headers from Apple:
  39.                             most methods that returned references now have "Ref" at
  40.                             the end of their methods names to prevent possible collisions
  41.                             with datatypes and classes of the same name (older versions
  42.                             of the compiler didn't have a problem with this).
  43.     25-oct-95    -    ty    -    changes for "const" usage under CW7; simplification of Boolean
  44.                             query methods
  45.  
  46. */
  47.  
  48. /*===========================================================================*/
  49.  
  50. /*======= Segmentation directives ========*/
  51.  
  52. #ifdef USE_MANUAL_SEGMENTATION
  53. #pragma segment ty
  54. #endif
  55.  
  56. /*============ Header files ==============*/
  57.     
  58. #include     "ABLinkedList.h"
  59.  
  60. /*=============== Globals ================*/
  61.  
  62. /*================ CODE ==================*/
  63.  
  64. /*=============================== ABLink::ABLink ================================*/
  65.  
  66. ABLink::ABLink(void)
  67. {
  68.     mPreviousLink = NULL;
  69.     mThisLink = this;
  70.     mNextLink = NULL;
  71.  
  72. }    // end ABLink
  73.  
  74.  
  75. /*=============================== ABLink::~ABLink ================================*/
  76.  
  77. ABLink::~ABLink(void)
  78. {
  79.     this->Unlink();
  80. }    // end ~ABLink
  81.  
  82.  
  83. /*=============================== ABLink::Data ================================*/
  84. void    *ABLink::Data(void)
  85. {
  86.     //    this function should be overridden!!!
  87.     return NULL;
  88. }    // end Data
  89.  
  90.  
  91.         
  92.  
  93. /*=============================== ABLink::FindHead ================================*/
  94. ABLink    *ABLink::FindHead(void)
  95. {
  96.     ABLink    *thing = this;
  97.     
  98.     while (thing->HasPreviousLink())
  99.     {
  100.         thing = thing->PreviousLink();
  101.     }    // end while block
  102.     
  103.     if (thing->DoesntHaveThisLink())
  104.         //    we've found the ABLinkedList "head" element,
  105.         //    so back off once and find the first element, if
  106.         //    one does indeed exist
  107.         return thing->NextLink();
  108.     else
  109.         //    nope, this must be a disembodied link item,
  110.         //    without the proper "head" or "tail" elements
  111.         //    present in an ABLinkedList
  112.         return thing;
  113. } // end FindHead
  114.  
  115.  
  116.  
  117.  
  118. /*=============================== ABLink::FindTail ================================*/
  119. ABLink    *ABLink::FindTail(void)
  120. {
  121.     ABLink    *thing = this;
  122.     
  123.     while (thing->HasNextLink())
  124.     {
  125.         thing = thing->NextLink();
  126.     }
  127.     
  128.     if (thing->DoesntHaveThisLink())
  129.         //    we've found the ABLinkedList "tail" element,
  130.         //    so back off once and find the last element, if
  131.         //    one does indeed exist
  132.         return thing->PreviousLink();
  133.     else
  134.         //    nope, this must be a disembodied link item,
  135.         //    without the proper "head" or "tail" elements
  136.         //    present in an ABLinkedList
  137.         return thing;
  138. } // end FindTail
  139.  
  140.  
  141.  
  142. /*=============================== ABLink::Unlink ================================*/
  143. void    ABLink::Unlink(void)
  144. {
  145.     if (this->HasPreviousLink())
  146.         this->PreviousLink()->NextLink() = this->NextLink();
  147.     
  148.     if (this->HasNextLink())
  149.         this->NextLink()->PreviousLink() = this->PreviousLink();
  150.     
  151. } // end Unlink
  152.  
  153.  
  154.  
  155.  
  156. /*=============================== ABLink::ExchangeWith ================================*/
  157. //
  158. //    This method will return the _OLD_ link, the one that you are replacing.
  159. //
  160. ABLink    *ABLink::ExchangeWith(ABLink *newGuy)
  161. {
  162.     if (newGuy)
  163.     {
  164.         ABLink    *link;
  165.     
  166.         //    previousNode    <---+                            <----+
  167.         //        previous        |                                 |
  168.         //        next        --+ |                            ---+ |
  169.         //                      | |                               | |
  170.         //    this            <-+    |  <+        newGuy            <--+ | <+
  171.         //        previous    ----+   |            previous    -----+  |
  172.         //        next        --+     |            next        ---+    |
  173.         //                      |     |                           |    |
  174.         //    nextNode        <-+     |                        <--+    |
  175.         //        previous    --------+                        --------+
  176.         //        next        
  177.         //
  178.         if (this->HasPreviousLink())
  179.             this->PreviousLink()->NextLink() = newGuy;
  180.         link = this->PreviousLink();
  181.         this->PreviousLink() = newGuy->PreviousLink();
  182.         newGuy->PreviousLink() = link;
  183.         
  184.         if (this->HasNextLink())
  185.             this->NextLink()->PreviousLink() = newGuy;
  186.         link = this->NextLink();
  187.         this->NextLink() = newGuy->NextLink();
  188.         newGuy->NextLink() = link;
  189.     } // end if block
  190.     
  191.     return this;
  192.     
  193. } // end ExchangeWith
  194.  
  195.  
  196.  
  197.  
  198. /*=============================== ABLink::Ordinal ================================*/
  199. ABIndex    ABLink::Ordinal(void)
  200. {
  201.     ABLink    *head;
  202.     ABLink    *tail;
  203.     ABLink    *t;
  204.     
  205.     ABIndex    marker;
  206.     
  207.     //    begin here...
  208.     
  209.     if (!(this->HasPreviousLink() && this->HasNextLink()))
  210.     {
  211.         return 1;
  212.     } else {
  213.         head = this->FindHead();
  214.         tail = this->FindTail();
  215.  
  216.         marker = 1;
  217.         t = head;
  218.         while ((t != this) && (t != tail))
  219.         {
  220.             t = t->NextLink();
  221.             ++marker;
  222.         } // end while
  223.         
  224.             
  225.         if (t == this)
  226.             return marker;
  227.         else
  228.             return 0;
  229.     } // end if else block
  230. } // end Ordinal
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239. /*=============================== ABLinkedList::ABLinkedList ================================*/
  240. ABLinkedList::ABLinkedList(void)
  241. {
  242.     mListCount = 0;
  243.     mHead.PreviousLink() = mHead.ThisLink() = NULL;
  244.     mHead.NextLink() = NULL;
  245.     mTail.PreviousLink() = NULL;
  246.     mTail.NextLink() = mTail.ThisLink() = NULL;
  247.     mCurrentLink = NULL;
  248. } // end ABLinkedList
  249.  
  250.  
  251. /*=============================== ABLinkedList::~ABLinkedList ================================*/
  252. ABLinkedList::~ABLinkedList(void)
  253. {
  254.     ABLink    *link = NULL;
  255.     
  256.     while (this->IsntEmpty())
  257.     {
  258.         link = this->NthLink(this->Count());
  259.         if (link)
  260.             link->Unlink();
  261.         delete link;
  262.         --(this->ListCount());
  263.     } // end while
  264.     
  265. }    // end ~ABLinkedList
  266.  
  267.  
  268.  
  269.  
  270.  
  271. /*=============================== ABLinkedList::Append ================================*/
  272. ABLinkedList    *ABLinkedList::Append(ABLink *item)
  273. {
  274.     if (this->Tail().HasPreviousLink())
  275.     {
  276.         //    point the last item to this new item
  277.         this->Tail().PreviousLink()->NextLink() = item;
  278.     } // end if block
  279.     
  280.     //    make the new item the last item
  281.     item->NextLink() = &(this->Tail());
  282.     //    point new item back to the former last item
  283.     item->PreviousLink() = this->Tail().PreviousLink();
  284.     this->Tail().PreviousLink() = item;
  285.     
  286.     if (this->Head().DoesntHaveNextLink())
  287.     {
  288.         //    make the new item the first item
  289.         this->Head().NextLink() = item;
  290.         item->PreviousLink() = &(this->Head());
  291.     } // end if block
  292.         
  293.     ++(this->ListCount());
  294.     this->CurrentLink() = item;
  295.     
  296.     return this;
  297. } // end Append
  298.  
  299.  
  300.  
  301.  
  302. /*=============================== ABLinkedList::Delete ================================*/
  303. ABLinkedList    *ABLinkedList::Detach(ABLink *item)
  304. {
  305.     if (item)
  306.     {
  307.         if (item == this->CurrentLink())
  308.             this->CurrentLink() = item->PreviousLink();
  309.         if (this->DoesntHaveCurrentLink())
  310.             this->CurrentLink() = & this->Head();
  311.             
  312.         item->Unlink();
  313.     }
  314.      // end if block
  315.      
  316.     return this;
  317.     
  318. } // end Detach
  319.  
  320.  
  321.  
  322.  
  323. /*=============================== ABLinkedList::NthLink ================================*/
  324. ABLink    *ABLinkedList::NthLink(ABIndex n)
  325. {
  326.     ABIndex    index;
  327.     ABLink    *link;
  328.     
  329.     //    begin here...
  330.     
  331.     if ((this->Count() < 1) || (n > this->Count())) 
  332.         return NULL;
  333.     
  334.     link = &(this->Head());
  335.     for (index = 1; (index <= n) && link; ++index)
  336.     {
  337.         link = link->NextLink();
  338.     } // end for loop
  339.     
  340.     if (link == &(this->Tail()))
  341.         return NULL;
  342.     else
  343.         return link;
  344. } // end NthLink
  345.  
  346.  
  347.  
  348. /*=============================== ABLinkedList::GotoLink ================================*/
  349. ABLink    *ABLinkedList::GotoLink(ABIndex n)
  350. {
  351.     ABLink    *link;
  352.     
  353.     //    begin here...
  354.     
  355.     link = this->NthLink(n);
  356.     if (link)
  357.         this->CurrentLink() = link;
  358.         
  359.     return link;
  360. } // end GotoLink
  361.  
  362.  
  363.  
  364. /*=============================== ABLinkedList::PreviousLink ================================*/
  365. ABLink    *ABLinkedList::PreviousLink(void)
  366. {
  367.     if (this->DoesntHaveCurrentLink())
  368.         return NULL;
  369.         
  370.     if (this->CurrentLink()->PreviousLink() != &(this->Head()))
  371.         this->CurrentLink() = this->CurrentLink()->PreviousLink();
  372.  
  373.     return this->CurrentLink();
  374. } // end PreviousLink
  375.  
  376.  
  377.  
  378. /*=============================== ABLinkedList::NextLink ================================*/
  379. ABLink    *ABLinkedList::NextLink(void)
  380. {
  381.     if (this->DoesntHaveCurrentLink())
  382.         return NULL;
  383.         
  384.     if (this->CurrentLink()->NextLink() != &(this->Tail()))
  385.         this->CurrentLink() = this->CurrentLink()->NextLink();
  386.  
  387.     return this->CurrentLink();
  388. } // end NextLink
  389.  
  390.  
  391.  
  392. /*=============================== ABLinkedList::FirstLink ================================*/
  393. ABLink    *ABLinkedList::FirstLink(void)
  394. {
  395.     if (this->IsntEmpty())
  396.         return this->Head().NextLink();
  397.     else
  398.         return NULL;
  399. } // end FirstLink
  400.  
  401.  
  402.  
  403. /*=============================== ABLinkedList::LastLink ================================*/
  404. ABLink    *ABLinkedList::LastLink(void)
  405. {
  406.     if (this->IsntEmpty())
  407.         return this->Tail().PreviousLink();
  408.     else
  409.         return NULL;
  410. } // end LastLink
  411.  
  412.  
  413.  
  414. /*=============================== ABLinkedList::Concatenate ================================*/
  415. //
  416. //    ForEach is an internal method used to do something to all items in
  417. //    the list.
  418. OSErr    ABLinkedList::ForEach (ABMessage /* message */, void* /* data*/)
  419. {
  420.     //    OVERRIDE THIS METHOD...
  421.     return noErr;
  422. } /// end ForEach
  423.  
  424.  
  425.  
  426.  
  427. // end of file.
  428.